﻿// -----------------------------------------------------------------------
// <copyright file="AudioEqualizer.cs" company="Abyssalsoft">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace Core.Player.Audio.Filters
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Un4seen.Bass;
    using Un4seen.Bass.Misc;

    /// <summary>
    /// Equalizer control with 10 bands channel
    /// </summary>
    internal class AudioEqualizer
    {
        /// <summary>Array of equalizer bands</summary>
        private int[] fxEQ = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

        /// <summary>Temporary array</summary>
        private int[] eqValues = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

        /// <summary>Initializes a new instance of the AudioEqualizer class.</summary>
        internal AudioEqualizer()
        {
            Events.Instance.Play += new EventHandler(this.OnPlay);
        }

        /// <summary>
        /// Update values
        /// </summary>
        internal void SyncronizeAllValues()
        {
            int bandCounter = 0;
            foreach (int value in this.eqValues)
            {
                this.SetEqualizer(bandCounter, value);
                bandCounter++;
            }
        }

        /// <summary>Update equalizer values</summary>
        /// <param name="band">Band to update</param>
        /// <param name="gain">Float gain value</param>
        internal void SetEqualizer(int band, int gain)
        {
            try
            {
                // Reverse sign
                int reversedValue = gain * -1;

                BASS_DX8_PARAMEQ eq = new BASS_DX8_PARAMEQ();
                if (Bass.BASS_FXGetParameters(this.fxEQ[band], eq))
                {
                    ////eq.fGain = gain / 10f;
                    eq.fGain = reversedValue / 10f;
                    Bass.BASS_FXSetParameters(this.fxEQ[band], eq);
                }

                // Stores the value in our array
                ////this.EqValues[band] = reversedValue;
                this.eqValues[band] = gain;
            }
            catch
            {
            }
        }

        /// <summary>
        /// Initialize equalizer on play event
        /// </summary>
        /// <param name="sender">Object sender</param>
        /// <param name="e">Event args</param>
        private void OnPlay(object sender, EventArgs e)
        {
            BASS_DX8_PARAMEQ eq;
            eq = null;

            // 10-band EQ
            eq = new BASS_DX8_PARAMEQ();

            for (int i = 0; i < 10; i++)
            {
                this.fxEQ[i] = Bass.BASS_ChannelSetFX(AudioCommon.Instance.Stream, BASSFXType.BASS_FX_DX8_PARAMEQ, 0);
            }

            eq.fBandwidth = 18f;

            // Low
            eq.fCenter = 80f;
            Bass.BASS_FXSetParameters(this.fxEQ[0], eq);

            eq.fCenter = 180f;
            Bass.BASS_FXSetParameters(this.fxEQ[1], eq);

            eq.fCenter = 310f;
            Bass.BASS_FXSetParameters(this.fxEQ[2], eq);

            eq.fCenter = 600f;
            Bass.BASS_FXSetParameters(this.fxEQ[3], eq);

            // Middle
            eq.fCenter = 1000f;
            Bass.BASS_FXSetParameters(this.fxEQ[4], eq);

            eq.fCenter = 3000f;
            Bass.BASS_FXSetParameters(this.fxEQ[5], eq);

            eq.fCenter = 6000f;
            Bass.BASS_FXSetParameters(this.fxEQ[6], eq);

            // High
            eq.fCenter = 10000f;
            Bass.BASS_FXSetParameters(this.fxEQ[7], eq);

            eq.fCenter = 12000f;
            Bass.BASS_FXSetParameters(this.fxEQ[8], eq);

            eq.fCenter = 15000f;
            Bass.BASS_FXSetParameters(this.fxEQ[9], eq);

            // The song has changed, apply values again
            this.SyncronizeAllValues();
        }
    }
}
